home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / pinfocom_3_0.lha / Source / input.c < prev    next >
C/C++ Source or Header  |  1992-10-22  |  12KB  |  520 lines

  1. /* input.c
  2.  *
  3.  *  ``pinfocom'' -- a portable Infocom Inc. data file interpreter.
  4.  *  Copyright (C) 1987-1992  InfoTaskForce
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; see the file COPYING.  If not, write to the
  18.  *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * $Header: RCS/input.c,v 3.0 1992/10/21 16:56:19 pds Stab $
  23.  */
  24.  
  25. #include <string.h>
  26. #include <errno.h>
  27. #include <ctype.h>
  28.  
  29. #include "infocom.h"
  30.  
  31. #ifdef NEED_ERRNO
  32. extern int errno;
  33. #endif
  34.  
  35. static word    coded[2];
  36.  
  37. static word
  38. convert A1(char, ch)
  39. {
  40.     extern char     table[];
  41.  
  42.     char            *ptr;
  43.     word            code;
  44.  
  45.     ptr = table;
  46.     while ((*ptr != ch) && (*ptr != 0))
  47.         ++ptr;
  48.     if (*ptr == 0)
  49.         return (0);
  50.     code = (ptr - table) + 6;
  51.     while (code >= 0x20)
  52.         code -= 0x1A;
  53.     return (code);
  54. }
  55.  
  56. static word
  57. find_mode A1(char, ch)
  58. {
  59.     if (ch == 0)
  60.         return (3);
  61.     if ((ch >= 'a') && (ch <= 'z'))
  62.         return (0);
  63.     if ((ch >= 'A') && (ch <= 'Z'))
  64.         return (1);
  65.     return (2);
  66. }
  67.  
  68. static void
  69. encode A1(byte*, the_word)
  70. {
  71.     word    data[6];
  72.     word    mode;
  73.     word    offset;
  74.     byte    *ptr;
  75.     byte    ch;
  76.     int     count;
  77.  
  78.     count = 0;
  79.     ptr = the_word;
  80.     while (count < 6)
  81.     {
  82.         ch = *ptr++;
  83.         if (ch == 0)
  84.         {
  85.             /* Finished, so fill with blanks */
  86.  
  87.             while (count < 6)
  88.                 data[count++] = 5;
  89.         }
  90.         else
  91.         {
  92.             /* Get Character Print-Mode */
  93.  
  94.             mode = find_mode(ch);
  95.             if (mode != 0)
  96.                 data[count++] = mode + 3;
  97.  
  98.             /* Get offset of character in Table[] */
  99.  
  100.             if (count < 6)
  101.             {
  102.                 offset = convert(ch);
  103.                 if (offset == 0)
  104.                 {
  105.                     /* Character not in Table[], so use ASCII */
  106.  
  107.                     data[count++] = 6;
  108.                     if (count < 6)
  109.                         data[count++] = ch >> 5;
  110.                     if (count < 6)
  111.                         data[count++] = ch & 0x1F;
  112.                 }
  113.                 else
  114.                     data[count++] = offset;
  115.             }
  116.         }
  117.     }
  118.  
  119.     /* Encrypt */
  120.  
  121.     coded[0] = (data[0] << 10) | (data[1] << 5) | data[2];
  122.     coded[1] = (data[3] << 10) | (data[4] << 5) | data[5];
  123.     coded[1] |= 0x8000;
  124. }
  125.  
  126. void
  127. ti_escape A1(char *, cmd)
  128. {
  129.     char *cp;
  130.     int val = -1;
  131.  
  132.     /*
  133.      * If no arg was given, print the possibilities
  134.      */
  135.     if (*cmd == '\0')
  136.     {
  137.         char buf[81];
  138.  
  139.         scr_putline("Interpreter command list:");
  140.         scr_putline("");
  141.  
  142.         F2_SETB(B_FIXED_FONT);
  143.  
  144.         sprintf(buf, "  atest:  %s  Attribute test display",
  145.                 gflags.pr_atest ? "[on] " : "[off]");
  146.         scr_putline(buf);
  147.  
  148.         sprintf(buf, "  attr:   %s  Attribute assignment display",
  149.                 gflags.pr_attr ? "[on] " : "[off]");
  150.         scr_putline(buf);
  151.  
  152.         sprintf(buf, "  echo:   %s  Input line echoing",
  153.                 gflags.echo ? "[on] " : "[off]");
  154.         scr_putline(buf);
  155.  
  156.         sprintf(buf, "  pager:  %s  Output paging",
  157.                 gflags.paged ? "[on] " : "[off]");
  158.         scr_putline(buf);
  159.  
  160.         sprintf(buf, "  prompt: %s  Alternate prompt flag",
  161.                 F1_IS_SET(B_ALT_PROMPT) ? "[on] " : "[off]");
  162.         scr_putline(buf);
  163.  
  164.         sprintf(buf, "  status: %s  Status line display",
  165.                 gflags.pr_status ? "[on] " : "[off]");
  166.         scr_putline(buf);
  167.  
  168.         sprintf(buf, "  tandy:  %s  Tandy license flag",
  169.                 F1_IS_SET(B_TANDY) ? "[on] " : "[off]");
  170.         scr_putline(buf);
  171.  
  172.         sprintf(buf, "  xfers:  %s  Object transfer display",
  173.                 gflags.pr_xfers ? "[on] " : "[off]");
  174.         scr_putline(buf);
  175.  
  176.         F2_RESETB(B_FIXED_FONT);
  177.         scr_putline("");
  178.  
  179.         return;
  180.     }
  181.  
  182.     /*
  183.      * Lowercase the command and find the end of it (it might have
  184.      * arguments: none do currently but...).
  185.      */
  186.     for (cp=cmd; isalpha(*cp); ++cp)
  187.         *cp = isupper(*cp) ? tolower(*cp) : *cp;
  188.     *(cp++) = '\0';
  189.  
  190.     if (!strcmp(cmd, "tandy"))
  191.     {
  192.         cp = "tandy";
  193.         if (F1_IS_SET(B_TANDY))
  194.         {
  195.             F1_RESETB(B_TANDY);
  196.             val = 0;
  197.         }
  198.         else
  199.         {
  200.             F1_SETB(B_TANDY);
  201.             val = 1;
  202.         }
  203.     }
  204.     else if (!strcmp(cmd, "prompt"))
  205.     {
  206.         cp = "prompt";
  207.         if (F1_IS_SET(B_ALT_PROMPT))
  208.         {
  209.             F1_RESETB(B_ALT_PROMPT);
  210.             val = 0;
  211.         }
  212.         else
  213.         {
  214.             F1_SETB(B_ALT_PROMPT);
  215.             val = 1;
  216.         }
  217.     }
  218.     else if (!strcmp(cmd, "status"))
  219.     {
  220.         cp = "status";
  221.         val = gflags.pr_status = !gflags.pr_status;
  222.     }
  223.     else if (!strcmp(cmd, "pager"))
  224.     {
  225.         cp = "pager";
  226.         val = gflags.paged = !gflags.paged;
  227.     }
  228.     else if (!strcmp(cmd, "echo"))
  229.     {
  230.         cp = "echo";
  231.         val = gflags.echo = !gflags.echo;
  232.     }
  233.     else if (!strcmp(cmd, "attr"))
  234.     {
  235.         cp = "attr";
  236.         val = gflags.pr_attr = !gflags.pr_attr;
  237.     }
  238.     else if (!strcmp(cmd, "atest"))
  239.     {
  240.         cp = "atest";
  241.         val = gflags.pr_atest = !gflags.pr_atest;
  242.     }
  243.     else if (!strcmp(cmd, "xfers"))
  244.     {
  245.         cp = "xfers";
  246.         val = gflags.pr_xfers = !gflags.pr_xfers;
  247.     }
  248.     else
  249.     {
  250.         char buf[81];
  251.  
  252.         sprintf(buf, "Invalid interpreter command: `%s'", cmd);
  253.         scr_putmesg(buf, 1);
  254.     }
  255.  
  256.     if (val >= 0)
  257.     {
  258.         char buf[80];
  259.  
  260.         sprintf(buf, "[%s := %s]", cp, val ? "ON" : "OFF");
  261.         scr_putline(buf);
  262.         scr_putline("");
  263.     }
  264. }
  265.  
  266. static byte
  267. *read_line A2(byte*, prompt, byte*, buffer)
  268. {
  269.     extern char script_fn[];
  270.  
  271.     static FILE *sfp = NULL;
  272.     char *cp;
  273.  
  274.     set_score();
  275.  
  276.     if ((sfp != NULL) && !F2_IS_SET(B_SCRIPTING))
  277.     {
  278.         scr_close_sf(script_fn, sfp, SF_SCRIPT);
  279.         sfp = NULL;
  280.     }
  281.  
  282.  retry:
  283.     cp = (char *)&buffer[1];
  284.     scr_getline((char *)prompt, *buffer, cp);
  285.  
  286.     /*
  287.      * If we're echoing, print the command.
  288.      */
  289.     if (gflags.echo)
  290.         scr_putline(cp);
  291.  
  292.     /*
  293.      * Lowercase all the input, then return a ptr to the end of the
  294.      * buffer.  ANSI C tolower() accepts non-uppercase chars and does
  295.      * the right thing, but not everyone does...
  296.      */
  297.     for (; *cp != '\0'; ++cp)
  298.         *cp = isupper((int)*cp) ? tolower((int)*cp) : *cp;
  299.  
  300.     /*
  301.      * If we're not already scripting and the command is not "script"
  302.      * we're done.  Otherwise call scr_open_sf().  If it succeeds,
  303.      * we're done.  If not, print a failure and get a new command
  304.      */
  305.     if (sfp == NULL)
  306.     {
  307.         extern word vocab_entry_size;
  308.         const char *pp;
  309.  
  310.         pp = (char *)&buffer[1];
  311.         if (!strncmp(pp, "script", 6))
  312.         {
  313.             pp += 6;
  314.  
  315.             /*
  316.              * In v3 games chuck any chars after 6: i.e., the user
  317.              * could type "scriptydoo" and the interpreter would see
  318.              * just "script".
  319.              */
  320.             if (vocab_entry_size <= 7)
  321.                 while ((*pp != '\0') && !isspace(*pp))
  322.                     ++pp;
  323.             /*
  324.              * Skip any ending whitespace
  325.              */
  326.             while ((*pp != '\0') && isspace(*pp))
  327.                 ++pp;
  328.  
  329.             if ((*pp == '\0')
  330.                 && ((sfp = scr_open_sf( MAXPATHLEN+1,
  331.                                         script_fn,
  332.                                         SF_SCRIPT )) == NULL))
  333.             {
  334.                 if (errno != 0)
  335.                     f_error(errno, "Cannot open script file `%s'", script_fn);
  336.                 scr_putline("Failed.");
  337.                 scr_putline("");
  338.                 goto retry;
  339.             }
  340.         }
  341.     }
  342.  
  343.     return ((byte *)cp);
  344. }
  345.  
  346. static void
  347. look_up A2(byte*, the_word, byte*, word_ptr)
  348. {
  349.     extern word     num_vocab_words;
  350.     extern word     vocab_entry_size;
  351.     extern byte     *base_ptr;
  352.     extern byte     *strt_vocab_table;
  353.     extern byte     *end_vocab_table;
  354.  
  355.     byte    *vocab_strt;
  356.     byte    *v_ptr;
  357.     word    first;
  358.     word    second;
  359.     word    shift;
  360.     word    chop;
  361.     word    offset;
  362.     Bool    found;
  363.  
  364.     encode(the_word);
  365.     shift = num_vocab_words;
  366.     chop = vocab_entry_size;
  367.     shift >>= 1;
  368.     do
  369.     {
  370.         chop <<= 1;
  371.         shift >>= 1;
  372.     }
  373.     while (shift != 0);
  374.     vocab_strt = strt_vocab_table + chop - vocab_entry_size;
  375.  
  376.     found = 0;
  377.     do
  378.     {
  379.         chop >>= 1;
  380.         v_ptr = vocab_strt;
  381.         first = Z_TO_WORD_I(v_ptr);
  382.         if (first == coded[0])
  383.         {
  384.             second = Z_TO_WORD_I(v_ptr);
  385.             if (second == coded[1])
  386.                 found = 1;
  387.             else
  388.             {
  389.                 if (coded[1] > second)
  390.                 {
  391.                     vocab_strt += chop;
  392.                     if (vocab_strt > end_vocab_table)
  393.                         vocab_strt = end_vocab_table;
  394.                 }
  395.                 else
  396.                     vocab_strt -= chop;
  397.             }
  398.         }
  399.         else
  400.         {
  401.             if (coded[0] > first)
  402.             {
  403.                 vocab_strt += chop;
  404.                 if (vocab_strt > end_vocab_table)
  405.                     vocab_strt = end_vocab_table;
  406.             }
  407.             else
  408.                 vocab_strt -= chop;
  409.         }
  410.     }
  411.     while ((chop >= vocab_entry_size) && (!found));
  412.  
  413.     if (!found)
  414.         offset = 0;
  415.     else
  416.         offset = vocab_strt - base_ptr;
  417.  
  418.     *(word_ptr + 1) = (byte)offset;
  419.     *word_ptr = (byte)(offset >> 8);
  420. }
  421.  
  422. static void
  423. parse A3(byte*, inb_strt, byte*, inb_end, byte*, word_buff_strt)
  424. {
  425.     extern byte     *wsbf_strt;
  426.     extern byte     *end_of_sentence;
  427.  
  428.     byte    *last_word;
  429.     byte    *word_ptr;
  430.     byte    *char_ptr;
  431.     byte    *ws;
  432.     byte    the_word[8];
  433.     byte    word_count;
  434.     byte    ch;
  435.     int     i;
  436.     Bool    white_space;
  437.  
  438.     word_count = 0;
  439.     char_ptr = inb_strt + 1;
  440.     word_ptr = word_buff_strt + 2;
  441.  
  442.     i = 0;
  443.     while ((char_ptr != inb_end) || (i != 0))
  444.     {
  445.         i = 0;
  446.         last_word = char_ptr;
  447.         white_space = 0;
  448.         while ((char_ptr != inb_end) && (!white_space))
  449.         {
  450.             ch = *char_ptr++;
  451.             ws = wsbf_strt;
  452.             while ((*ws != ch) && (*ws != '\0'))
  453.                 ++ws;
  454.             if (*ws == ch)
  455.             {
  456.                 white_space = 1;
  457.                 if (i != 0)
  458.                     --char_ptr;
  459.                 if ((i == 0) && (ws < end_of_sentence))
  460.                     the_word[i++] = ch;
  461.             }
  462.             else
  463.             {
  464.                 if (i < 6)
  465.                     the_word[i++] = ch;
  466.             }
  467.         }
  468.  
  469.         if (i != 0)
  470.         {
  471.  
  472.             /* First byte of buffer contains the buffer length */
  473.  
  474.             if (word_count == *word_buff_strt)
  475.             {
  476.                 scr_putline("Too many words typed. Flushing: ");
  477.                 *inb_end = 0;
  478.                 scr_putline((char *)last_word);
  479.                 *inb_end = 0;
  480.  
  481.                 new_line();
  482.                 *(word_buff_strt + 1) = *word_buff_strt;
  483.                 return;
  484.             }
  485.             else
  486.             {
  487.                 ++word_count;
  488.                 *(word_ptr + 2) = (byte)(char_ptr - last_word);
  489.                 *(word_ptr + 3) = (byte)(last_word - inb_strt);
  490.                 the_word[i] = 0;
  491.                 look_up(the_word, word_ptr);
  492.                 word_ptr += 4;
  493.             }
  494.         }
  495.     }
  496.  
  497.     word_buff_strt[1] = word_count;
  498. }
  499.  
  500. void
  501. input A2(word, char_offset, word, word_offset)
  502. {
  503.     extern print_buf_t  *pbf_p;
  504.     extern byte         *base_ptr;
  505.  
  506.     byte *inb_strt;
  507.     byte *inb_end;
  508.  
  509.     /*
  510.      * Get an input line and parse it
  511.      */
  512.     pbf_p->buf[pbf_p->len] = '\0';
  513.  
  514.     inb_strt = base_ptr + char_offset;
  515.     inb_end = read_line(pbf_p->buf, inb_strt);
  516.     parse(inb_strt, inb_end, base_ptr + word_offset);
  517.  
  518.     pbf_p->len = 0;
  519. }
  520.